package com.android.lovely.ui.widget

import android.content.Context
import android.util.AttributeSet
import android.widget.FrameLayout
import android.widget.Toast
import androidx.core.view.isVisible
import androidx.core.widget.doAfterTextChanged
import com.android.lovely.R
import com.android.lovely.data.CreateImageDetail
import com.android.lovely.data.ImageGenerateData
import com.android.lovely.data.ParameterValue
import com.android.lovely.databinding.ItemKeyNormalWordBinding
import com.android.lovely.databinding.ItemKeyWordBinding
import com.android.lovely.databinding.ViewCreateKeyBinding
import com.android.lovely.framework.BaseAdapter
import com.google.android.flexbox.FlexboxLayoutManager
import com.kotlin.extensions.appContext
import com.kotlin.extensions.inflater.LayoutInflaterExt.layoutInflater
import com.kotlin.extensions.keyboard.hideKeyboard
import com.kotlin.extensions.view.ViewExt.clickable

/**
 *
 * @author why
 * @date 2025/4/11 11:05
 */
class CreateKeyWidget(context: Context, attrs: AttributeSet?) : FrameLayout(context, attrs) {
    private val mBinding by lazy {
        ViewCreateKeyBinding.inflate(layoutInflater, this, false)
    }
    val adapter by lazy {
        EditableTagAdapter()
    }
    val keyAdapter by lazy {
        SelectableTagAdapter()
    }

    private var detail: CreateImageDetail? = null
    private var nsfwSwitch = false

    private fun calculateMaxSelection(): Int {
        return if (detail?.multipleSelection == 0) 1 else detail?.maxOptions ?: 1
    }

    init {
        addView(mBinding.root)
        mBinding.rvFlag.layoutManager = FlexboxLayoutManager(context)
        mBinding.rvFlag.adapter = adapter

        mBinding.rvKey.layoutManager = FlexboxLayoutManager(context)
        mBinding.rvKey.adapter = keyAdapter

        mBinding.addKey.isEnabled = false

        adapter.onDelete = { tag ->
            val items = keyAdapter.getItems().find { data -> data.title == tag.title }
            items?.isSelected = false
            keyAdapter.notifyDataSetChanged()
            checkAdd()
        }
        keyAdapter.onItemClick = onItemClickListener@{ item, position ->
            item ?: return@onItemClickListener
            val select = item.isSelected
            item.isSelected = !select
            if (!select && adapter.getItems().size >= calculateMaxSelection()) {
                Toast.makeText(
                    appContext, appContext.getString(
                        R.string.max_length_key, item.title, calculateMaxSelection().toString()
                    ), Toast.LENGTH_SHORT
                ).show()
                return@onItemClickListener
            }
            if (item.isSelected) adapter.insert(item) else adapter.delete(item)
            keyAdapter.notifyItemChanged(position)
            checkAdd()
        }
    }

    fun updateContent(nsfw: Boolean, data: CreateImageDetail?) {
        data ?: return
        this.detail = data
        this.nsfwSwitch = nsfw
        mBinding.roleTitle.setMust(data.required == 1)
        mBinding.roleTitle.setTitle(data.title)
        keyAdapter.updateList(
            copyList(if (nsfw) data.nsfwEnabledValues else data.nsfwDisabledValues)
        )
        adapter.updateList(data.selectedValue)
        mBinding.key.doAfterTextChanged {
            mBinding.addKey.isEnabled = it.isNullOrBlank().not()
        }
        mBinding.addKey.clickable {
            mBinding.key.clearFocus()
            adapter.insert(
                ParameterValue(
                    mBinding.key.text.toString(),
                    mBinding.key.text.toString()
                )
            )
            checkAdd()
            mBinding.key.text?.clear()
            hideKeyboard()
        }
    }

    private fun copyList(list: List<ParameterValue>): List<ParameterValue> {
        val newList = mutableListOf<ParameterValue>()
        list.forEach { newList.add(it.copy()) }
        return newList
    }

    private fun checkAdd() {
        if (adapter.getItems().size >= calculateMaxSelection()) {
            mBinding.key.isEnabled = false
            mBinding.addKey.isEnabled = false
        } else {
            mBinding.key.isEnabled = true
            mBinding.addKey.isEnabled = mBinding.key.text?.isNotBlank() == true
        }
    }

    fun getDetail(): CreateImageDetail? {
        return detail
    }

    fun applyAISuggestions(details: List<CreateImageDetail>?) {
        val data = details?.find { it.codeValue == (detail?.codeValue ?: "") }
        keyAdapter.getItems().forEach { tags ->
            tags.isSelected = data?.contentList?.any { it.title == tags.title || it.description == tags.description } == true
        }
        keyAdapter.notifyDataSetChanged()
        adapter.updateList(data?.contentList ?: arrayListOf())
    }

    private fun resetInputFields() {
        mBinding.key.clearFocus()
        mBinding.key.text?.clear()
        mBinding.addKey.isEnabled = false
    }

    fun clear() {
        adapter.updateList(arrayListOf())
        keyAdapter.updateList(copyList(
            if (nsfwSwitch) detail?.nsfwEnabledValues ?: arrayListOf()
            else detail?.nsfwDisabledValues ?: arrayListOf())
        )
        resetInputFields()
    }

    fun refresh(nsfw: Boolean) {
        nsfwSwitch = nsfw
        adapter.updateList(arrayListOf())
        keyAdapter.updateList(copyList(
            if (nsfw) detail?.nsfwEnabledValues ?: arrayListOf()
            else detail?.nsfwDisabledValues ?: arrayListOf())
        )
        resetInputFields()
    }

    fun validateInput() : Boolean {
        return if (detail?.required == 1) adapter.getItems().isNotEmpty() else true
    }

    fun applyHistoryData(data: List<ParameterValue>?) {
        keyAdapter.getItems().forEach { tags ->
            tags.isSelected = data?.any { it.title == tags.title || it.description == tags.description } == true
        }
        keyAdapter.notifyDataSetChanged()

        adapter.updateList(data ?: arrayListOf())
    }

    fun getSelectedParameters(): Pair<String, List<String>> {
        return Pair(detail?.codeValue ?: "", adapter.getItems().map { it.description })
    }
}

class EditableTagAdapter(val isEdit: Boolean = true) : BaseAdapter<ParameterValue, ItemKeyWordBinding>() {
    var onDelete: (ParameterValue) -> Unit = {}

    override fun bindViewWithHolderDetails(
        holder: ViewHolder,
        item: ParameterValue?,
        binding: ItemKeyWordBinding,
        position: Int
    ) {
        binding.tvKey.text = item?.title ?: ""
        binding.ivClose.isVisible = isEdit
        binding.ivClose.clickable {
            deleteAt(position)
            item?.let { onDelete.invoke(it) }
        }
    }
}

class SelectableTagAdapter : BaseAdapter<ParameterValue, ItemKeyNormalWordBinding>() {
    override fun bindViewWithHolderDetails(
        holder: ViewHolder,
        item: ParameterValue?,
        binding: ItemKeyNormalWordBinding,
        position: Int
    ) {
        binding.tvKey.text = item?.title ?: ""
        binding.tvKey.isSelected = item?.isSelected == true
        binding.tvKey.clickable {
            onItemClick?.invoke(item, position)
        }
    }
}